#!/usr/bin/env python
from __future__ import print_function
from __future__ import division

from OpenGL.GL import *
from os import path, curdir
from pprint import pprint
from Engine import Textures
import Options


dirt_ground = Textures.Texture('Sand0083_L.png')
print(dirt_ground.IsBound())
print(dirt_ground.IsValid())
#dirt_wall_1 = Textures.Texture(GL_TEXTURE_2D)
#dirt_wall_1.LoadImage('Sand0137_1_L.jpg')
#dirt_wall_2 = Textures.Texture(GL_TEXTURE_2D)
#dirt_wall_2.LoadImage('Sand0137_2_L.jpg')


class Tile(object):
    def __init__(self, x, y, z, width, height, depth):
        self.x = x
        self.y = y
        self.z = z
        self.width = width
        self.height = height
        self.depth = depth
        self.terrainType = "Dirt"
        self.dug = False
        self.claimer = None
        self.room = None
        self.fortified = False

    def __repr__(self):
        return "<Tile x={0}, y={1}, z={2}, terrainType={3}, dug={4}, claimer={5}, room={6}, fortified={7}>".format(str(self.x), str(self.y), str(self.z), str(self.terrainType), str(self.dug), str(self.claimer), str(self.room), str(self.fortified))

    def dump(self, f):
        f.write("{0},{1},{2};{3},{4};{5},{6},{7}\n".format(self.x, self.y, self.z,\
                                                         self.terrainType,\
                                                         self.dug,\
                                                         self.claimer,\
                                                         self.room,\
                                                         self.fortified))

class Map(object):
    def __init__(self, width, height, depth):
        self.width = width
        self.height = height
        self.depth = depth
        if self.width < 1:
            self.width = 1
        if self.height < 1:
            self.height = 1
        if self.depth < 1:
            self.depth = 1
        self.tiles = list()
        for z in range(self.depth):
            for y in range(self.height):
                for x in range(self.width):
                    self.tiles.append(Tile(x, y, z, 1.0, 1.0, 1.0))

    def load(self, map_name):
        self.tiles = list()
        with open(path.join(Options.MapsLocation, map_name+Options.MapsExtension), "r") as f:
            for line in f.readlines():
                if line.startswith("#"):
                    continue
                parts = line.split(";")
                if len(parts) == 1 and parts[0] == '':
                    continue
                position, terrain, alterations = parts
                x, y, z = position.split(",")
                terrainType, dug = terrain.split(",")
                if dug == "True":
                    dug = True
                else:
                    dug = False
                claimer, room, fortified = alterations.split(",")
                if claimer == "None":
                    claimer = None
                if room == "None":
                    room = None
                if fortified == "True":
                    fortified = True
                else:
                    fortified = False
                tile = Tile(float(x), float(y), float(z), 1.0, 1.0, 1.0)
                tile.terrainType = terrainType
                tile.dug = dug
                tile.claimer = claimer
                tile.room = room
                tile.fortified = fortified
                self.tiles.append(tile)
        tile = self.tiles[-1]
        self.width = tile.x+1.0
        self.height = tile.y+1.0
        self.depth = tile.z+1.0

    def save(self, map_name):
        with open(path.join(map_dir, map_name+map_ext), "wb") as f:
            for tile in self.tiles:
                tile.dump(f)

    def build(self):
        self.vertices = list()
        self.tile_v_indices = list()
        for tile in self.tiles:
            if tile.dug:
                left_bottom = (tile.x, tile.y, tile.z)
                left_top = (tile.x, tile.y+tile.height, tile.z)
                right_top = (tile.x+tile.width, tile.y+tile.height, tile.z)
                right_bottom = (tile.x+tile.width, tile.y, tile.z)

                if self.vertices.count(left_bottom) < 1:
                    self.vertices.append(left_bottom)
                if self.vertices.count(left_top) < 1:
                    self.vertices.append(left_top)
                if self.vertices.count(right_top) < 1:
                    self.vertices.append(right_top)
                if self.vertices.count(right_bottom) < 1:
                    self.vertices.append(right_bottom)
        self.vertices.sort()
        for tile in self.tiles:
            if tile.dug:
                left_bottom = (tile.x, tile.y, tile.z)
                left_top = (tile.x, tile.y+tile.height, tile.z)
                right_top = (tile.x+tile.width, tile.y+tile.height, tile.z)
                right_bottom = (tile.x+tile.width, tile.y, tile.z)
                self.tile_v_indices.append(self.vertices.index(left_bottom))
                self.tile_v_indices.append(self.vertices.index(left_top))
                self.tile_v_indices.append(self.vertices.index(right_top))
                self.tile_v_indices.append(self.vertices.index(right_bottom))

        glEnableClientState(GL_VERTEX_ARRAY)
        glVertexPointer(3, GL_DOUBLE, 0, self.vertices)
        glEnableClientState(GL_TEXTURE_COORD_ARRAY)
        self.tex_coords = list()
        for i in range(len(self.vertices)):
            self.tex_coords.append(0.0)
            self.tex_coords.append(-1.0)
            self.tex_coords.append(0.0)
            self.tex_coords.append(0.0)
            self.tex_coords.append(1.0)
            self.tex_coords.append(0.0)
            self.tex_coords.append(1.0)
            self.tex_coords.append(-1.0)
        glTexCoordPointer(2, GL_FLOAT, 0, self.tex_coords)

    def draw(self):
        dirt_ground.Bind()
        glColor(1.0, 0.0, 1.0, 1.0)
        glDrawElements(GL_QUADS, len(self.tile_v_indices), GL_UNSIGNED_INT, self.tile_v_indices)
